package zwxsrv

import (
	"fmt"
	"sync"
)

type TextHandler func(text string) (msg string, goon bool, err error)
type EventHandler func(event string) (msg string, err error)

// 微信服务响应业务管理
type WxHandlerMan struct {
	sync.RWMutex

	textHandlers  []TextHandler           // 文本回调
	eventHandlers map[string]EventHandler // 事件回调
}

func NewWxHandlerMan() *WxHandlerMan {
	return &WxHandlerMan{
		eventHandlers: make(map[string]EventHandler),
	}
}

// text 消息
func (whm *WxHandlerMan) addTextHandler(h TextHandler) error {
	whm.Lock()
	defer whm.Unlock()

	// 是否已经存在，注意函数不能直接比较
	sh := fmt.Sprintf("%v", h)
	for i := 0; i < len(whm.textHandlers); i++ {
		if fmt.Sprintf("%v", whm.textHandlers[i]) == sh {
			return nil
		}
	}

	whm.textHandlers = append(whm.textHandlers, h)
	return nil
}

func (whm *WxHandlerMan) delTextHandler(h TextHandler) error {
	whm.Lock()
	defer whm.Unlock()

	// 注意函数不能直接比较
	sh := fmt.Sprintf("%v", h)
	for i := 0; i < len(whm.textHandlers); i++ {
		if fmt.Sprintf("%v", whm.textHandlers[i]) == sh {
			whm.textHandlers = append(whm.textHandlers[:i], whm.textHandlers[i+1:]...)
			return nil
		}
	}
	return nil
}

func (whm *WxHandlerMan) handleText(text string) (string, error) {
	whm.RLock()
	defer whm.RUnlock()

	for i := 0; i < len(whm.textHandlers); i++ {
		if h := whm.textHandlers[i]; h != nil {
			msg, goon, err := h(text)
			if err != nil {
				return "", err
			}
			if goon {
				continue
			}
			return msg, nil
		}
	}

	return "", fmt.Errorf("no handler care")
}

// event 消息
func (whm *WxHandlerMan) setEventHandler(event string, h EventHandler) error {
	whm.Lock()
	defer whm.Unlock()

	if _, ok := whm.eventHandlers[event]; ok {
		return fmt.Errorf("event handler has already exist")
	}

	whm.eventHandlers[event] = h
	return nil
}

func (whm *WxHandlerMan) delEventHandler(event string) error {
	whm.Lock()
	defer whm.Unlock()

	if _, ok := whm.eventHandlers[event]; ok {
		delete(whm.eventHandlers, event)
	}
	return nil
}

func (whm *WxHandlerMan) handleEvent(event string) (string, error) {
	whm.RLock()
	defer whm.RUnlock()

	h, ok := whm.eventHandlers[event]
	if !ok {
		return "", fmt.Errorf("no handler care")
	}

	return h(event)
}

// 处理微信消息
func nextHandler(requestBody *RequestBody) {
	// 判断用户
	if requestBody.FromUserName != gCfg.AdminOpenID {
		SendTextVarServer(requestBody.FromUserName, "本公众平台只对管理员提供服务")
		return
	}

	// 文本消息
	if requestBody.MsgType == "text" || requestBody.MsgType == "voice" {
		content := requestBody.Content + requestBody.Recognition
		msg, err := gWxHandlerMan.handleText(content)
		if err != nil {
			msg = err.Error()
		}
		if msg != "" {
			SendTextVarServer(requestBody.FromUserName, msg)
		}
		return
	}

	// 事件消息
	if requestBody.MsgType == "event" {
		msg, err := gWxHandlerMan.handleEvent(requestBody.EventKey)
		if err != nil {
			msg = err.Error()
		}
		if msg != "" {
			SendTextVarServer(requestBody.FromUserName, msg)
		}
		return
	}

	//其它消息
	SendTextVarServer(requestBody.FromUserName, "不支持的消息类型:"+requestBody.MsgType)
	return
}
